package com.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dto.UserRoleDto;
import com.example.dto.UserStatusDto;
import com.example.entity.LoginUser;
import com.example.entity.Role;
import com.example.entity.User;
import com.example.entity.UserRole;
import com.example.service.RoleService;
import com.example.service.UserRoleService;
import com.example.service.UserService;
import com.example.mapper.UserMapper;
import com.example.utils.*;
import com.example.vo.BlogUserLoginVo;
import com.example.vo.PageVo;
import com.example.vo.UserInfoVo;
import com.example.vo.UserRoleIdVo;
import com.qiniu.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author sprite-pc
* @description 针对表【sys_user(用户表)】的数据库操作Service实现
* @createDate 2023-12-17 22:14:45
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{


    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleService roleService;


    @Override
    public ResponseResult login(User user) {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(),user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        //判断是否认证通过
        if(Objects.isNull(authenticate)){
            throw new RuntimeException("用户名或密码错误");
        }
        //获取userid 生成token
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        String userId = loginUser.getUser().getId().toString();
        String jwt = JwtUtil.createJWT(userId);
        //把用户信息存入redis
        redisCache.setCacheObject("adminLogin:"+userId,loginUser);

        //把token和userinfo封装 返回
        //把User转换成UserInfoVo
        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(loginUser.getUser(), UserInfoVo.class);
        BlogUserLoginVo vo = new BlogUserLoginVo(jwt,userInfoVo);
        return ResponseResult.okResult(vo);
    }

    @Override
    public ResponseResult userInfo(Long id) {
        //获取当前用户id
        Long userId = SecurityUtils.getUserId();
        //根据用户id查询用户信息
        User user = getById(userId);
        //封装成UserInfoVo
        UserInfoVo vo = BeanCopyUtils.copyBean(user,UserInfoVo.class);
        return ResponseResult.okResult(vo);
    }

    @Override
    public ResponseResult register(User user) {
        user.setCreateTime(new Date());
//        passwordEncoder();
//        user.setPassword();
        user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));

        save(user);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult updateUserInfo(User user) {

        User userLogin = BeanCopyUtils.copyBean(user,User.class);
        updateById(userLogin);
        return ResponseResult.okResult();

    }

    @Override
    public ResponseResult getList(int pageNum, int pageSize, String userName, String phonenumber, String status) {
        LambdaQueryWrapper<User> queryWrapper =new LambdaQueryWrapper<>();

        if (!StringUtils.isNullOrEmpty(userName)){
            queryWrapper.like(User::getUserName,userName);

        }
        if (!StringUtils.isNullOrEmpty(phonenumber)){
            queryWrapper.like(User::getPhonenumber,phonenumber);
        }
        if(!StringUtils.isNullOrEmpty(status)){
            queryWrapper.eq(User::getStatus,status);
        }
        Page<User> userPage = new Page<>(pageNum,pageSize);
        page(userPage,queryWrapper);
        PageVo pageVo = new PageVo(userPage.getRecords(),userPage.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult changeStatus(UserStatusDto userStatusDto) {
        User user = getById(userStatusDto.getUserId());
        user.setStatus(userStatusDto.getStatus());
        updateById(user);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getUser(Long id) {
        UserRoleIdVo userRoleIdVo = new UserRoleIdVo();
        userRoleIdVo.setUser(getById(id));
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(UserRole::getUserId,id);
        List<UserRole> rolesList = userRoleService.list(queryWrapper);
        List<String> roleIds = rolesList.stream().map(role ->{
            return role.getRoleId().toString();
        }).collect(Collectors.toList());
        userRoleIdVo.setRoleIds(roleIds);

        userRoleIdVo.setRoles(roleService.list());
        return ResponseResult.okResult(userRoleIdVo);
    }

    @Override
    public ResponseResult updateUser(UserRoleDto userRoleDto) {
        List<String> roleIds = userRoleDto.getRoleIds();
        if (roleIds!=null){
            LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserRole::getUserId,userRoleDto.getId());
            userRoleService.remove(queryWrapper);
            for (String roleId:roleIds){
                UserRole userRole = new UserRole();
                userRole.setRoleId(new Long(roleId));
                userRole.setUserId(userRoleDto.getId());
                userRoleService.save(userRole);
            }
        }

        User user = BeanCopyUtils.copyBean(userRoleDto,User.class);
        updateById(user);
        return ResponseResult.okResult();
    }
}




